/**
 * 双端队列接口模块。
 * License: BSD
 * Authors: Lucifer (786325481@QQ.com)
 * Copyright: Copyright (C) 2008 Lucifer. All rights reserved.
 */

module system.collections.IDeque;

import system.collections.IEnumerable;
import system.collections.ICollection;
import system.collections.IQueue;

/**
 * 双端队列接口，支持在两端插入和移除元素。
 * 此接口定义在双端队列两端访问元素的方法。
 * 提供插入、移除和检查元素的方法。
 * Comments:
 *		大多数双端队列实现，对于它们能够包含的元素数没有固定限制，
 *		但此接口既支持有容量限制的双端队列，也支持没有固定大小限制的双端队列。
 *
 *		该接口每种方法都存在两种形式：
 *		一种形式在操作失败时抛出异常，
 *		另一种形式返回一个特殊值（null 或 false，具体取决于操作）。
 *		插入操作的后一种形式是专为使用有容量限制的 Deque 实现设计的；
 *		在大多数实现中，插入操作不会失败。
 *
 * 		此接口扩展了 IQueue(T) 接口。
 *		在将双端队列用作队列时，将得到 FIFO（先进先出）行为。
 *		将元素添加到双端队列的末尾，从双端队列的开头移除元素。 
 *		从 IQueue(T) 接口继承的方法完全等效于 IDeque(T) 方法。
 *
 *		双端队列也可用作 LIFO（后进先出）堆栈。
 *		在将双端队列用作堆栈时，元素被推入双端队列的开头并从双端队列开头弹出。
 *		堆栈方法完全等效于 Deque 方法。
 *
 *		与 IList(T) 接口不同，此接口不支持通过索引访问元素。
 *
 *		虽然 IDeque(T) 实现没有严格要求禁止插入 null 元素，但建议最好不要插入 null 。
 *		这是因为各种方法会将该类型的初始值用作特殊的返回值来指示双端队列为空。
 *		对于值类型或者基元类型则返回类型初始值，对于引用类型来说则是 null 。 
 */
public interface IDeque(T) : IEnumerable!(T), ICollection!(T), IQueue!(T)
{
	///将指定元素插入此双端队列的开头（如果可以直接这样做而不违反容量限制）。
	void addFirst(T item);

	///在不违反容量限制的情况下，将指定的元素插入此双端队列的开头。
	bool tryAddFirst(T item);

	///将指定元素插入此双端队列的末尾（如果可以直接这样做而不违反容量限制）。
	void addLast(T item);	

	///在不违反容量限制的情况下，将指定的元素插入此双端队列的末尾。
	bool tryAddLast(T item);

	/**
	 * 将指定元素插入此双端队列所表示的队列（换句话说，此双端队列的尾部），
	 * 如果可以直接这样做而不违反容量限制的话；
	 * 如果成功，则返回 true，如果当前没有可用的空间，则返回 false。
	 */
	bool tryAdd(T item);

	///获取并移除此双端队列所表示的队列的头部（换句话说，此双端队列的第一个元素）。
	T remove();

	///获取并移除此双端队列第一个元素。
	T removeFirst();

	///从此双端队列移除第一次出现的指定元素。
	bool removeFirstOccurrence(T item);

	///获取并移除此双端队列的最后一个元素。
	T removeLast();

	///从此双端队列移除最后一次出现的指定元素。
	bool removeLastOccurrence(T item);

	/**
	 * 获取并移除此双端队列所表示的队列的头部（换句话说，此双端队列的第一个元素）；
	 * 如果此双端队列为空，则返回 false。
	 */
	bool tryRemove(out T item);

	///获取并移除此双端队列的第一个元素；如果此双端队列为空，则返回 false。
	bool tryRemoveFirst(out T item);

	///获取并移除此双端队列的最后一个元素；如果此双端队列为空，则返回 false。
	bool tryRemoveLast(out T item);

	///获取，但不移除此双端队列的第一个元素。
	T peekFirst();

	///获取，但不移除此双端队列的最后一个元素。
	T peekLast();

	///获取，但不移除此双端队列的第一个元素；如果此双端队列为空，则返回 false。
	bool tryPeekFirst(out T item);

	///获取，但不移除此双端队列的最后一个元素；如果此双端队列为空，则返回 false。
	bool tryPeekLast(out T item);

	///从此双端队列所表示的堆栈中弹出一个元素。
	T pop();

	/**
	 * 将一个元素推入此双端队列所表示的堆栈（换句话说，此双端队列的头部），
	 * 如果可以直接这样做而不违反容量限制的话；
	 * 如果成功，则返回 true，如果当前没有可用空间，则抛出 InvalidOperationException。
	 */
	void push(T item);
}